function diagnose_training_issues(trainFolder, trainImgPerPerson)
% 诊断训练数据的潜在问题
% 
% 输入:
%   trainFolder - 训练集文件夹路径 
%   trainImgPerPerson - 每个人使用的训练图像数量

if nargin < 1
    trainFolder = 'D:\文档资料\OneDrive\桌面\人脸配准(眉毛特征点)\train';
end

if nargin < 2
    trainImgPerPerson = 5;
end

fprintf('===== 训练数据诊断工具 =====\n');
fprintf('训练文件夹: %s\n', trainFolder);
fprintf('每人训练图像数: %d\n', trainImgPerPerson);
fprintf('\n');

% 检查文件夹是否存在
if ~exist(trainFolder, 'dir')
    error('训练文件夹不存在: %s', trainFolder);
end

% 1. 获取所有图像文件
fprintf('【步骤1】扫描所有图像文件...\n');
imgExtensions = {'.jpg', '.png', '.bmp', '.jpeg', '.tif'};
allFiles = [];

for i = 1:length(imgExtensions)
    pattern = ['*' imgExtensions{i}];
    files = dir(fullfile(trainFolder, pattern));
    fprintf('    %s文件: %d个\n', imgExtensions{i}, length(files));
    allFiles = [allFiles; files];
end

fprintf('    总计: %d个图像文件\n\n', length(allFiles));

% 2. 解析文件名
fprintf('【步骤2】解析文件名格式...\n');
personData = containers.Map('KeyType', 'int32', 'ValueType', 'any');
invalidFiles = {};

for i = 1:length(allFiles)
    filename = allFiles(i).name;
    tokens = regexp(filename, '(\d+)[-_](\d+)', 'tokens');
    
    if ~isempty(tokens)
        personID = str2double(tokens{1}{1});
        imageSeq = str2double(tokens{1}{2});
        
        if isKey(personData, personID)
            data = personData(personID);
            data.sequences(end+1) = imageSeq;
            data.filenames{end+1} = filename;
            data.count = data.count + 1;
            personData(personID) = data;
        else
            data = struct();
            data.sequences = imageSeq;
            data.filenames = {filename};
            data.count = 1;
            personData(personID) = data;
        end
    else
        invalidFiles{end+1} = filename;
    end
end

% 输出解析结果
personIDs = sort(cell2mat(keys(personData)));
fprintf('    成功解析: %d个文件\n', length(allFiles) - length(invalidFiles));
fprintf('    格式错误: %d个文件\n', length(invalidFiles));
fprintf('    人物总数: %d\n', length(personIDs));

if ~isempty(invalidFiles)
    fprintf('\n    格式错误的文件:\n');
    for i = 1:length(invalidFiles)
        fprintf('      %s\n', invalidFiles{i});
    end
end

% 3. 分析每个人的图像数量
fprintf('\n【步骤3】分析每个人的图像分布...\n');
fprintf('人物ID  图像数量  序号范围      缺失序号    训练后剩余\n');
fprintf('------  --------  ----------    --------    ----------\n');

problemPersons = [];
totalTrainingImages = 0;

for i = 1:length(personIDs)
    personID = personIDs(i);
    data = personData(personID);
    
    % 分析序号
    sequences = sort(data.sequences);
    minSeq = min(sequences);
    maxSeq = max(sequences);
    expectedCount = maxSeq - minSeq + 1;
    actualCount = length(sequences);
    
    % 查找缺失的序号
    missingSeqs = [];
    for seq = minSeq:maxSeq
        if ~ismember(seq, sequences)
            missingSeqs(end+1) = seq;
        end
    end
    
    % 计算训练后剩余图像数
    usedForTraining = min(trainImgPerPerson, actualCount);
    remainingImages = actualCount - usedForTraining;
    totalTrainingImages = totalTrainingImages + usedForTraining;
    
    % 输出信息
    fprintf('%6d  %8d  %d-%d        ', personID, actualCount, minSeq, maxSeq);
    
    if isempty(missingSeqs)
        fprintf('无       ');
    else
        if length(missingSeqs) <= 3
            fprintf('%s   ', sprintf('%d ', missingSeqs));
        else
            fprintf('%d个      ', length(missingSeqs));
        end
    end
    
    fprintf('%10d\n', remainingImages);
    
    % 标记有问题的人物
    if actualCount < trainImgPerPerson || ~isempty(missingSeqs)
        problemPersons(end+1) = personID;
    end
end

fprintf('\n总计将使用 %d 张图像进行训练\n', totalTrainingImages);

% 4. 分析潜在问题
fprintf('\n【步骤4】问题分析...\n');

if ~isempty(problemPersons)
    fprintf('发现 %d 个人物存在潜在问题:\n', length(problemPersons));
    for i = 1:length(problemPersons)
        personID = problemPersons(i);
        data = personData(personID);
        
        fprintf('  人物ID %d:\n', personID);
        if data.count < trainImgPerPerson
            fprintf('    - 图像数量不足 (%d < %d)\n', data.count, trainImgPerPerson);
        end
        
        sequences = sort(data.sequences);
        minSeq = min(sequences);
        maxSeq = max(sequences);
        missingSeqs = [];
        for seq = minSeq:maxSeq
            if ~ismember(seq, sequences)
                missingSeqs(end+1) = seq;
            end
        end
        
        if ~isempty(missingSeqs)
            fprintf('    - 序号不连续，缺失: %s\n', sprintf('%d ', missingSeqs));
        end
        
        fprintf('    - 现有文件: %s\n', sprintf('%s ', data.filenames{:}));
    end
else
    fprintf('✓ 未发现明显问题\n');
end

% 5. 解决方案建议
fprintf('\n【步骤5】解决方案建议...\n');

fprintf('针对"识别时找不到对比照片"的问题:\n');
fprintf('  ✓ 已修复代码，不再固定要求序号为1的图像\n');
fprintf('  ✓ 现在会查找该人物ID的任意一张图像作为展示\n\n');

fprintf('针对"训练时样本数量不足"的问题:\n');
fprintf('  ✓ 已修改为按序号顺序选择训练图像，而非随机选择\n');
fprintf('  ✓ 这样可以确保训练的一致性和可重现性\n\n');

if ~isempty(problemPersons)
    fprintf('针对发现的具体问题:\n');
    fprintf('  - 检查文件命名是否符合"人物ID-序号"或"人物ID_序号"格式\n');
    fprintf('  - 考虑补充缺失的图像文件\n');
    fprintf('  - 或者调整trainImgPerPerson参数，使其不超过最少图像数量\n');
end

fprintf('\n===== 诊断完成 =====\n');

end 